package com.mzj.saas.sdk.pay.callback;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.AlipaySignature;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

public class AliPayCallback extends AbstractPayCallback{
	
	private final static Logger logger = LoggerFactory.getLogger(AliPayCallback.class);
	private static final String CHARSET = "UTF-8";
	private static final String SIGN_TYPE = "RSA2";
	private String appid;
	
	private String publicKey;
	
	private HttpServletRequest request;
	
	private HttpServletResponse response;
	
	private Map<String, String> params;
	
	
	public AliPayCallback(String appid,String publicKey,HttpServletRequest request,HttpServletResponse response) {
		this.appid = appid;
		this.publicKey = publicKey;
		this.request = request;
		this.response = response;
	}
	
	@Override
	protected String key() {
		// TODO Auto-generated method stub
		return publicKey;
	}

	/**
	 * 回调参数
	 * https://opendocs.alipay.com/open/204/105301
     * 6.验证交易通知状态, 在支付宝的业务通知中，只有交易通知状态为 TRADE_SUCCESS(支付成功) 或 TRADE_FINISHED(交易完结)时，支付宝才会认定为买家付款成功。
     * 注意：
     *  1.状态TRADE_SUCCESS的通知触发条件是商户签约的产品支持退款功能的前提下，买家付款成功；
     *  2.交易状态TRADE_FINISHED的通知触发条件是商户签约的产品不支持退款功能的前提下，买家付款成功；或者，商户签约的产品支持退款功能的前提下，交易已经成功并且已经超过可退款期限。
     *
	 * return null错误 ,返回相关数据
	 */
	@Override
	public Map<String, String> verifyResult() {
		// TODO Auto-generated method stub
		try {
			 // 解析,重组参数
            Map<String, String[]> requestParams = request.getParameterMap();
            logger.info("[AliPay verifySignature Notity] Request Params: {}", JSONObject.toJSONString(requestParams));
            params = new LinkedHashMap<>();
            Iterator<String> iterator = requestParams.keySet().iterator();
            while (iterator.hasNext()) {
                String name = (String) iterator.next();
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }
            
            String trade_no = params.get("trade_no");
            String out_trade_no = params.get("out_trade_no");
            String total_amount = params.get("total_amount"); // 订单金额，元
            String app_id = params.get("app_id");
            String trade_status = params.get("trade_status");
            String passback_params = params.get("passback_params");
            String notifyTime  =  params.get("notify_time");
            String sellerId  =  params.get("seller_id");
            String buyerId  =  params.get("buyer_id");
            logger.info("[AliPay verifySignature Notity] trade_status={}, trade_no={}, out_trade_no={}, total_amount={}, app_id={}", trade_status, trade_no, out_trade_no, total_amount, app_id);

            if (StringUtils.isBlank(trade_no) || StringUtils.isBlank(out_trade_no) || StringUtils.isBlank(total_amount)
            	 || StringUtils.isBlank(app_id) || StringUtils.isBlank(trade_status)) {
            	logger.error("verifySignature ---> 异步通知中有参数为空！");
            	return null;
			}
            
            if (appid != null && !appid.equals(app_id)) {
            	logger.error("payCallback ---> [systemAppid={}, zfbReturnAppid={}]appid非我商户本身的appid！", appid, app_id);
            	return null;
			}
            
           //验证签名
           if(publicKey != null && !AlipaySignature.rsaCheckV1(params, publicKey, CHARSET, SIGN_TYPE)) {
            	logger.error("[AliPay Callback Notity] Sign Check Failed!");
              	return null;
           }
           
           Map<String, String> result = new HashMap<String, String>();
           result.put("tradeNo", trade_no);
           result.put("outTradeNo", out_trade_no);
           result.put("totalAmount", total_amount);
           result.put("appid", app_id);
           result.put("tradeStatus", trade_status);
           result.put("passbackParams", passback_params);
           result.put("notifyTime", notifyTime);
           result.put("sellerId", sellerId);
           result.put("buyerId", buyerId);
           return result;
		}catch(Exception e) {
			logger.error("支付宝支付结果回调通知-处理异常", e);
		}
		return null;
	}


	@Override
	protected Map<String, String> getReqInfo(Map<String, String> packageParams) {
		return null;
	}

	/**
	 * 签名验证
	 * 支付宝公钥
	 */
	@Override
	public boolean verifySignature(String... values) {
		try {
			if(params == null) {
				return false;
			}
			
			if(!AlipaySignature.rsaCheckV1(params, values[0], CHARSET, SIGN_TYPE)) {
				logger.error("[AliPay Callback Notity] Sign Check Failed!");
	          	return false;
			}
		
			return true;
		}catch(Exception e) {
			logger.error("支付宝签名验证异常", e);
		}
		return false;
	}

	/**
	 * 返回成功消息
	 * 程序执行完后必须打印输出“success”（不包含引号）。如果商户反馈给支付宝的字符不是success这7个字符，支付宝服务器会不断重发通知，直到超过24小时22分钟。
     * 一般情况下，25小时以内完成8次通知（通知的间隔频率一般是：4m,10m,10m,1h,2h,6h,15h）。
	 */
	@Override
	public void resultSuccess() throws Exception{
		response.getWriter().write("success");
	}

	
	/**
	 * 返回失败消息
	 */
	@Override
	public void resultFail() throws Exception{
		response.getWriter().write("failure");
	}
}
